/**************
 * 1)  It's GNU implementation of huffman archiving method as a yearly project at university by alstein
 * 2)  Huffarch is being written under linux with vim, gdb, gcc, NetBeans IDE.
 * 3)  Considering author is very inexperienced programmer yet, don't judge too rough.
 **************/
#include "service.h"

/***************
 *SYNOPSIS
 *    arc -[axXdlt] arc[.ext] file1 file2 …
 *
 *FUNCTION LETTERS
 *   One of the following must be used:
 *
 *	-a (append)  – put files into archive
 *	-X (eXtract) – extract files out of archive NOT IMPLEMENTED YET
 *	-x (extract) – extract files and make paths relative
 *	-d (delete)  – delete files from archive
 *	-l (list)    – output the information about files in archive
 *	-t (test)    – check integrity of archive
 *****************/

// function carries out the analysis of the second argument from the command line

int analyse_command_line_arc_mode(unsigned char input[])
{
    if (input[0] != '-')
    {
	print_error(ARGS, (unsigned char*) "");
	return ERROR;
    }

    if (input[2]) //any odd function letters?
    {
	print_error(IGNORED_PARAMS, input);
    }

    switch (input[1])
    {
    case 'a': return APPEND;
	//case 'X': return EXTRACT_REL;
    case 'x': return EXTRACT;
    case 'd': return DELETE;
    case 'l': return LIST;
    case 't': return TEST;
	// not now =(
	//case 'b': return BLACKJACK;
    default: return ERROR;
    }
}

int main(int argc, char* argv[])
{
    FILE *f;
    arfile *root = NULL;
    int parameter;

    if (argc > 1) //are there args?
    {
	command = analyse_command_line_arc_mode((unsigned char*) argv[1]);
	switch (command)
	{
	case ERROR:
	    print_error(UNKNOWN_PARAM, (unsigned char*) argv[1]);
	    print_help_info();
	    break;

	case APPEND:
	    if (validate_filename((unsigned char*) argv[2]))
	    {
		print_error(FILENAME_INV_OR_NULL, (unsigned char*) "");
		return 1;
	    }
	    if (-1 == append_files(argc, (unsigned char**) argv))
		return -1;
	    break;

	case EXTRACT:
	    if (validate_filename((unsigned char*) argv[2]))
	    {
		print_error(FILENAME_INV_OR_NULL, (unsigned char*) "");
		return -1;
	    }
	    if (!(f = openFileRB((unsigned char*) argv[2])))
		return -1;

	    if (testIfRightArchiveFormat(f, (unsigned char*) argv[2]))
		return -1;

	    if (argc > 3)
		decodeByFilenames(f, (unsigned char**) argv, argc);
	    else
		decodeAllFiles(f);
	    break;

	case DELETE:
	    if (validate_filename((unsigned char*) argv[2]))
	    {
		print_error(FILENAME_INV_OR_NULL, (unsigned char*) "");
		return -1;
	    }

	    if (!(f = openFileRB((unsigned char*) argv[2])))
		return -1;

	    if (testIfRightArchiveFormat(f, (unsigned char*) argv[2]))
		return -1;

	    if (argc > 3)
		deleteByFilenames(f, (unsigned char**) argv, argc);
	    else
		print_error(FILENAME_INV_OR_NULL, (unsigned char*) "");

	    break;

	case LIST:
	    if (validate_filename((unsigned char*) argv[2]))
	    {
		print_error(FILENAME_INV_OR_NULL, (unsigned char*) "");
		return -1;
	    }

	    if (!(f = openFileRB((unsigned char*) argv[2])))
		return -1;

	    if (testIfRightArchiveFormat(f, (unsigned char*) argv[2]))
		return -1;


	    if (!(parameter = buildArfileList(f, &root)))
	    {
		printf("The contents of the archive %s:\n"\
				"%s\t\t\t%s\t%s\n", argv[2], "Name", "Compressed size", "Hash");
		traverseArfileTree(root);
	    }
	    if (-1 == parameter)
	    {
		print_error(SUBTEST_FAIL, (unsigned char*) argv[2]);
		return -1;
	    }
	    annihilate_arfiletree(root);
	    break;

	case TEST:
	    if (validate_filename((unsigned char*) argv[2]))
	    {
		print_error(FILENAME_INV_OR_NULL, (unsigned char*) "");
		return -1;
	    }

	    if (!(f = openFileRB((unsigned char*) argv[2])))
		return -1;

	    if (testIfRightArchiveFormat(f, (unsigned char*) argv[2]))
		return -1;

	    if (testIntegrity(f))
		printf("Archive integrity test failed.\n");
	    else
		printf("Archive intergity test passed successfully.\n");
	    break;

	}
    }
    else
    {
	print_help_info();
    }
    return 0;
}

